package com.zjhome.cloudnote.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.CustomAutowireConfigurer;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AndRequestMatcher;

import com.zjhome.cloudnote.filter.JWTAuthenticationFilter;
import com.zjhome.cloudnote.filter.JWTLoginFilter;
import com.zjhome.cloudnote.handler.Http401AuthenticationEntryPoint;
import com.zjhome.cloudnote.service.impl.CustomAuthenticationProvider;


/**
 * SpringSecurity 配置
 * >> 通过 SPringSecurity 的配置，将JWTLoginFilter，JWTAuthenticationFilter 组合在一起
 * 
 * @author 0283000121
 *
 */
@Configuration
@EnableWebSecurity
//@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	/**
	 * 白名单（需要放行的url） 
	 */
	public static final String[] AUTH_WHITELIST = {
			// -- register url
			"/users/signup",
			"/share/view/**",
			
			// -- swagger ui
			"/v2/api-docs",
			"/swagger-resources",
			"/swagger-resources/**",
			"/configuration/ui",
			"/configuration/security",
			"/swagger-ui.html",
			"/webjars/**"
	};
	
	@Autowired
	private UserDetailsService		userDetailsService;
	
	@Autowired
	private BCryptPasswordEncoder 	bCryptPasswordEncoder;
	
	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// 
		http.cors().and().csrf().disable()
			.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
			.and()
			.authorizeRequests()
			.antMatchers(AUTH_WHITELIST).permitAll()
			.anyRequest().authenticated()	// 所有请求需要身份认证
			.and()
			.exceptionHandling()
				.authenticationEntryPoint(
					new Http401AuthenticationEntryPoint("Basic realm=\"MyApp\"")
				)
			.and()
			.addFilter(new JWTLoginFilter(authenticationManager()))
			.addFilter(new JWTAuthenticationFilter(authenticationManager()))
			.logout()	// 默认注销行为为logout，可以通过下面的方法修改
			.logoutUrl("/logout")
			.logoutSuccessUrl("/login")// 设置注销成功后跳转页面，默认是跳转到登陆页面
//			.logoutSuccessHandler(logoutSuccessHandler)
			.permitAll();
	}
	
	/**
	 * 该方法登陆的时候会进入
	 */
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		// 使用自定义身份验证组件
		auth.authenticationProvider(
			new CustomAuthenticationProvider(userDetailsService, bCryptPasswordEncoder)
		);		
	}
}
